package com.hammera.common.baseUI

import android.accounts.NetworkErrorException
import android.app.Activity
import android.content.Context
import com.hammera.common.baseRx.HFlatMap
import com.hammera.common.baseRx.HSubscriber
import com.zzh.base.BaseModel
import com.zzh.base.baseRx.RxManager
import io.reactivex.Flowable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.Function
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException


/**
 * Created by din on 2018/8/7.
 * <p>
 * Email: godcok@163.com
 *
 */
abstract class BasePresenter<M : BaseModel<*>, V : BaseView> {
    protected var mRxManage = RxManager()
    protected var mContext: Context? = null
    protected var mActivity: Activity? = null
    protected var mModel: M? = null
    protected var mView: V? = null
    fun setMV(m: M?, v: V?) {
        this.mModel = m
        this.mView = v
    }

    fun setContext(context: Context?) {
        mContext = context?.applicationContext ?: context
    }


    fun setActivity(context: Activity?) {
        mActivity = context
    }

    fun onDestroy() {
        mActivity = null
        mRxManage.clear()
    }

    fun rxClear(){
        mRxManage.clear()
    }

    fun <T, R> toSubscribe(observable: Flowable<T>?, flatMap: HFlatMap<T, R>, observer: HSubscriber<R>) {
        observable?.flatMap { result -> Flowable.just(flatMap.apply(result)) }
                ?.subscribeOn(io.reactivex.schedulers.Schedulers.io())    // 指定subscribe()发生在IO线程
                ?.observeOn(AndroidSchedulers.mainThread())  // 指定Subscriber的回调发生在io线程
                ?.timeout(30, TimeUnit.SECONDS)    //重连间隔时间
//                ?.retry(3)
                ?.retryWhen(object : Function<Flowable<Throwable>, Flowable<*>> {

                    private var mRetryCount: Int = 0

                    @Throws(Exception::class)
                    override fun apply(throwableObservable: Flowable<Throwable>): Flowable<*> {



                        return throwableObservable.flatMap { throwable ->
                            if (throwable is NetworkErrorException
                                    || throwable is ConnectException
                                    || throwable is SocketTimeoutException
                                    || throwable is TimeoutException) {

                            }
                            mRetryCount++
                            if (mRetryCount <= 3)
                                Flowable.timer(3000, TimeUnit.MILLISECONDS)
                            else
                                Flowable.error<Any>(throwable)
                        }
                    }
                })
                ?.subscribe(observer)

        mRxManage.add(observer)   //订阅
    }

    fun <T> toSubscribe(observable: Flowable<T>?, observer: HSubscriber<T>) {
        observable?.subscribeOn(io.reactivex.schedulers.Schedulers.io())    // 指定subscribe()发生在IO线程
                ?.observeOn(AndroidSchedulers.mainThread())  // 指定Subscriber的回调发生在io线程
                ?.timeout(30, TimeUnit.SECONDS)    //重连间隔时间
//                ?.retry(3)
                ?.retryWhen(object : Function<Flowable<Throwable>, Flowable<*>> {

                    private var mRetryCount: Int = 0

                    @Throws(Exception::class)
                    override fun apply(throwableObservable: Flowable<Throwable>): Flowable<*> {
                        return throwableObservable.flatMap { throwable ->
                            if (throwable is NetworkErrorException
                                    || throwable is ConnectException
                                    || throwable is SocketTimeoutException
                                    || throwable is TimeoutException) {
                                mRetryCount++
                                if (mRetryCount <= 3)
                                    Flowable.timer(3000, TimeUnit.MILLISECONDS)
                                else
                                    Flowable.error<Any>(throwable)

                            } else {
                                Flowable.error<Any>(throwable)
                            }
                        }
                    }
                })
                ?.subscribe(observer)

        mRxManage.add(observer)   //订阅
    }

}